home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS02.ADF / Emacs / basic.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  9KB  |  287 lines

  1. /* basic.c */
  2.  
  3. /*
  4.  * The routines in this file move the cursor around on the screen. They
  5.  * compute a new value for the cursor, then adjust ".". The display code
  6.  * always updates the cursor location, so only moves between lines, or
  7.  * functions that adjust the top line in the window and invalidate the
  8.  * framing, are hard.
  9.  */
  10. #include        <stdio.h>
  11. #include        "ed.h"
  12.  
  13. /*
  14.  * Move the cursor to the
  15.  * beginning of the current line.
  16.  * Trivial.
  17.  */
  18. gotobol(f, n)
  19. {
  20.         curwp->w_doto  = 0;
  21.         return (TRUE);
  22. }
  23.  
  24. /*
  25.  * Move the cursor backwards by "n" characters. If "n" is less than zero call
  26.  * "forwchar" to actually do the move. Otherwise compute the new cursor
  27.  * location. Error if you try and move out of the buffer. Set the flag if the
  28.  * line pointer for dot changes.
  29.  */
  30. backchar(f, n)
  31. register int    n;
  32. {
  33.         register LINE   *lp;
  34.  
  35.         if (n < 0)
  36.                 return (forwchar(f, -n));
  37.         while (n--) {
  38.                 if (curwp->w_doto == 0) {
  39.                         if ((lp=lback(curwp->w_dotp)) == curbp->b_linep)
  40.                                 return (FALSE);
  41.                         curwp->w_dotp  = lp;
  42.                         curwp->w_doto  = llength(lp);
  43.                         curwp->w_flag |= WFMOVE;
  44.                 } else
  45.                         curwp->w_doto--;
  46.         }
  47.         return (TRUE);
  48. }
  49.  
  50. /*
  51.  * Move the cursor to the end of the current line. Trivial. No errors.
  52.  */
  53. gotoeol(f, n)
  54. {
  55.         curwp->w_doto  = llength(curwp->w_dotp);
  56.         return (TRUE);
  57. }
  58.  
  59. /*
  60.  * Move the cursor forwwards by "n" characters. If "n" is less than zero call
  61.  * "backchar" to actually do the move. Otherwise compute the new cursor
  62.  * location, and move ".". Error if you try and move off the end of the
  63.  * buffer. Set the flag if the line pointer for dot changes.
  64.  */
  65. forwchar(f, n)
  66. register int    n;
  67. {
  68.         if (n < 0)
  69.                 return (backchar(f, -n));
  70.         while (n--) {
  71.                 if (curwp->w_doto == llength(curwp->w_dotp)) {
  72.                         if (curwp->w_dotp == curbp->b_linep)
  73.                                 return (FALSE);
  74.                         curwp->w_dotp  = lforw(curwp->w_dotp);
  75.                         curwp->w_doto  = 0;
  76.                         curwp->w_flag |= WFMOVE;
  77.                 } else
  78.                         curwp->w_doto++;
  79.         }
  80.         return (TRUE);
  81. }
  82.  
  83. /*
  84.  * Goto the beginning of the buffer. Massive adjustment of dot. This is
  85.  * considered to be hard motion; it really isn't if the original value of dot
  86.  * is the same as the new value of dot. Normally bound to "M-<".
  87.  */
  88. gotobob(f, n)
  89. {
  90.         curwp->w_dotp  = lforw(curbp->b_linep);
  91.         curwp->w_doto  = 0;
  92.         curwp->w_flag |= WFHARD;
  93.         return (TRUE);
  94. }
  95.  
  96. /*
  97.  * Move to the end of the buffer. Dot is always put at the end of the file
  98.  * (ZJ). The standard screen code does most of the hard parts of update.
  99.  * Bound to "M->".
  100.  */
  101. gotoeob(f, n)
  102. {
  103.         curwp->w_dotp  = curbp->b_linep;
  104.         curwp->w_doto  = 0;
  105.         curwp->w_flag |= WFHARD;
  106.         return (TRUE);
  107. }
  108.  
  109. /*
  110.  * Move forward by full lines. If the number of lines to move is less than
  111.  * zero, call the backward line function to actually do it. The last command
  112.  * controls how the goal column is set. Bound to "C-N". No errors are
  113.  * possible.
  114.  */
  115. forwline(f, n)
  116. {
  117.         register LINE   *dlp;
  118.  
  119.         if (n < 0)
  120.                 return (backline(f, -n));
  121.         if ((lastflag&CFCPCN) == 0)             /* Reset goal if last   */
  122.                 curgoal = curcol;               /* not C-P or C-N       */
  123.         thisflag |= CFCPCN;
  124.         dlp = curwp->w_dotp;
  125.         while (n-- && dlp!=curbp->b_linep)
  126.                 dlp = lforw(dlp);
  127.         curwp->w_dotp  = dlp;
  128.         curwp->w_doto  = getgoal(dlp);
  129.         curwp->w_flag |= WFMOVE;
  130.         return (TRUE);
  131. }
  132.  
  133. /*
  134.  * This function is like "forwline", but goes backwards. The scheme is exactly
  135.  * the same. Check for arguments that are less than zero and call your
  136.  * alternate. Figure out the new line and call "movedot" to perform the
  137.  * motion. No errors are possible. Bound to "C-P".
  138.  */
  139. backline(f, n)
  140. {
  141.         register LINE   *dlp;
  142.  
  143.         if (n < 0)
  144.                 return (forwline(f, -n));
  145.         if ((lastflag&CFCPCN) == 0)             /* Reset goal if the    */
  146.                 curgoal = curcol;               /* last isn't C-P, C-N  */
  147.         thisflag |= CFCPCN;
  148.         dlp = curwp->w_dotp;
  149.         while (n-- && lback(dlp)!=curbp->b_linep)
  150.                 dlp = lback(dlp);
  151.         curwp->w_dotp  = dlp;
  152.         curwp->w_doto  = getgoal(dlp);
  153.         curwp->w_flag |= WFMOVE;
  154.         return (TRUE);
  155. }
  156.  
  157. /*
  158.  * This routine, given a pointer to a LINE, and the current cursor goal
  159.  * column, return the best choice for the offset. The offset is returned.
  160.  * Used by "C-N" and "C-P".
  161.  */
  162. getgoal(dlp)
  163. register LINE   *dlp;
  164. {
  165.         register int    c;
  166.         register int    col;
  167.         register int    newcol;
  168.         register int    dbo;
  169.  
  170.         col = 0;
  171.         dbo = 0;
  172.         while (dbo != llength(dlp)) {
  173.                 c = lgetc(dlp, dbo);
  174.                 newcol = col;
  175.                 if (c == '\t')
  176.                         newcol |= 0x07;
  177.                 else if (c<0x20 || c==0x7F)
  178.                         ++newcol;
  179.                 ++newcol;
  180.                 if (newcol > curgoal)
  181.                         break;
  182.                 col = newcol;
  183.                 ++dbo;
  184.         }
  185.         return (dbo);
  186. }
  187.  
  188. /*
  189.  * Scroll forward by a specified number of lines, or by a full page if no
  190.  * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
  191.  * the overlap; this value is the default overlap value in ITS EMACS. Because
  192.  * this zaps the top line in the display window, we have to do a hard update.
  193.  */
  194. forwpage(f, n)
  195. register int    n;
  196. {
  197.         register LINE   *lp;
  198.  
  199.         if (f == FALSE) {
  200.                 n = curwp->w_ntrows - 2;        /* Default scroll.      */
  201.                 if (n <= 0)                     /* Forget the overlap   */
  202.                         n = 1;                  /* if tiny window.      */
  203.         } else if (n < 0)
  204.                 return (backpage(f, -n));
  205. #if     CVMVAS
  206.         else                                    /* Convert from pages   */
  207.                 n *= curwp->w_ntrows;           /* to lines.            */
  208. #endif
  209.         lp = curwp->w_linep;
  210.         while (n-- && lp!=curbp->b_linep)
  211.                 lp = lforw(lp);
  212.         curwp->w_linep = lp;
  213.         curwp->w_dotp  = lp;
  214.         curwp->w_doto  = 0;
  215.         curwp->w_flag |= WFHARD;
  216.         return (TRUE);
  217. }
  218.  
  219. /*
  220.  * This command is like "forwpage", but it goes backwards. The "2", like
  221.  * above, is the overlap between the two windows. The value is from the ITS
  222.  * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
  223.  * reason.
  224.  */
  225. backpage(f, n)
  226. register int    n;
  227. {
  228.         register LINE   *lp;
  229.  
  230.         if (f == FALSE) {
  231.                 n = curwp->w_ntrows - 2;        /* Default scroll.      */
  232.                 if (n <= 0)                     /* Don't blow up if the */
  233.                         n = 1;                  /* window is tiny.      */
  234.         } else if (n < 0)
  235.                 return (forwpage(f, -n));
  236. #if     CVMVAS
  237.         else                                    /* Convert from pages   */
  238.                 n *= curwp->w_ntrows;           /* to lines.            */
  239. #endif
  240.         lp = curwp->w_linep;
  241.         while (n-- && lback(lp)!=curbp->b_linep)
  242.                 lp = lback(lp);
  243.         curwp->w_linep = lp;
  244.         curwp->w_dotp  = lp;
  245.         curwp->w_doto  = 0;
  246.         curwp->w_flag |= WFHARD;
  247.         return (TRUE);
  248. }
  249.  
  250. /*
  251.  * Set the mark in the current window to the value of "." in the window. No
  252.  * errors are possible. Bound to "M-.".
  253.  */
  254. setmark(f, n)
  255. {
  256.         curwp->w_markp = curwp->w_dotp;
  257.         curwp->w_marko = curwp->w_doto;
  258.         mlwrite("[Mark set]");
  259.         return (TRUE);
  260. }
  261.  
  262. /*
  263.  * Swap the values of "." and "mark" in the current window. This is pretty
  264.  * easy, bacause all of the hard work gets done by the standard routine
  265.  * that moves the mark about. The only possible error is "no mark". Bound to
  266.  * "C-X C-X".
  267.  */
  268. swapmark(f, n)
  269. {
  270.         register LINE   *odotp;
  271.         register int    odoto;
  272.  
  273.         if (curwp->w_markp == NULL) {
  274.                 mlwrite("No mark in this window");
  275.                 return (FALSE);
  276.         }
  277.         odotp = curwp->w_dotp;
  278.         odoto = curwp->w_doto;
  279.         curwp->w_dotp  = curwp->w_markp;
  280.         curwp->w_doto  = curwp->w_marko;
  281.         curwp->w_markp = odotp;
  282.         curwp->w_marko = odoto;
  283.         curwp->w_flag |= WFMOVE;
  284.         return (TRUE);
  285. }
  286.  
  287.